package com.nx.platform.es.biz.esspider.handler;

import com.google.common.base.Preconditions;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.nx.platform.es.biz.esspider.entity.Item;
import com.nx.platform.es.common.utils.MoreMaps;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.Strings;

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@HandlerDefine(HandlerType.SIMPLE)
public class SimpleExtraInfoConvertHandler extends AbstractSimpleHandler {

    private static final Type EXTRAINFO_TYPE = new TypeToken<Map<String, Object>>() {}.getType();
    private static final Logger LOGGER = LogManager.getLogger(SimpleExtraInfoConvertHandler.class);
    private static final Gson GSON = new GsonBuilder().create();

    private String field;
    private String videoField;

    @Override
    public void init(Map<?, ?> settings) throws Exception {
        field = MoreMaps.getString(settings, "field");
        Preconditions.checkNotNull(field, "extra info field not found");
        videoField = MoreMaps.getString(settings, "videoField");
    }

    @Override
    public void handle(Map<Long, Item> items) throws Exception {
        items.values().forEach((Item item) -> {
            Map<String, Object> paramsMap = convertParams(item.getDoc().remove(field));
            item.getDoc().put(field, convertParams(paramsMap));
            Object videosObj = paramsMap.get("videos");
            if (!Strings.isNullOrEmpty(videoField)) {
                boolean videos = videosObj != null && videosObj instanceof List && !((List<?>) videosObj).isEmpty();
                item.getDoc().put(videoField, videos);
            }
        });
    }

    private Map<String, Object> convertParams(Object object) {
        if (object != null && object instanceof String) {
            try {
                Map<String, Object> params = GSON.fromJson(String.valueOf(object), EXTRAINFO_TYPE);
                if (params != null) {
                    return params;
                }
            } catch (Throwable e) {
                LOGGER.warn("convert params error: {}", object, e);
            }
        }
        return new HashMap<>(0);
    }

    private Map<String, Integer> convertParams(Map<String, Object> paramsMap) {
        if (paramsMap != null) {
            Map<String, Integer> map = new HashMap<>(paramsMap.size());
            for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
                if (entry.getKey() != null && entry.getValue() != null) {
                    Integer paramValue = MoreMaps.getInteger(paramsMap, entry.getKey());
                    if (paramValue != null) {
                        map.put(entry.getKey().toLowerCase(), paramValue);
                    }
                }
            }
            return map;
        }
        return new HashMap<>(0);
    }

}
